#include <iostream>
#include "backtrace.h"
#include "fiber.h"

#include <unistd.h>
#include <thread>
#include <vector>

static ucontext_t g_ctx1;
static ucontext_t g_ctx2;
void test_print()
{
    while(1)
    {
        std::cout << "world" << std::endl;
        sleep(1);
        swapcontext(&g_ctx2, &g_ctx1);
    }
}

void test_context()
{
    const uint32_t stackSize = 2 * 1024;
    void* stack = std::malloc(stackSize);

    //获取线程上下文信息
    getcontext(&g_ctx2);
    g_ctx2.uc_link = nullptr;            //此协程函数执行完成后退出
    g_ctx2.uc_stack.ss_sp = stack;       //协程函数执行时 栈的起始地址
    g_ctx2.uc_stack.ss_size = stackSize; //栈大小

    makecontext(&g_ctx2, test_print, 0);

    while(1)
    {
        std::cout << "hello" << std::endl;

        swapcontext(&g_ctx1, &g_ctx2);
    }

}

void test_assert()
{
    // ASSERT(1 == 0);
    ASSERT2(1 == 0, "test assert");
}


void test_fiber()
{
    std::cout << "world ";
    Fiber::BackToHold();
    std::cout << "world2 ";
}

void creat_fiber()
{
    Fiber::GetThis();
    Fiber::ptr fiber(new Fiber(test_fiber, 0, false));

    std::cout << "hello ";
    fiber->call();
    std::cout << "!" << std::endl;

    std::cout << "hello2 ";
    fiber->call();
    std::cout << "!" << std::endl;
}

int main(void)
{
    // test_context();
    // test_assert();
    // creat_fiber();

    std::vector<std::thread> v;
    for(int i = 0; i < 3; ++i)
    {
        v.emplace_back(creat_fiber);
    }

    for(auto& t: v)
    {
        t.join();
    }

    return 0;
}
